package com.greensam.pixelengine.event.base;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 抽象事件类
 *
 * @author Ma Chengrui
 * @since 2025/10/13 17:36
 */
@Getter
@Setter
public abstract class AbstractTypeEvent<T extends TypeEvent> implements TypeEvent {

    public static final String WRAPPED_EVENT_OBJ = "eventObj";

    private Date eventTime = new Date();
    /**
     * 事件数据
     */
    protected Map<String, Object> data;

    protected AbstractTypeEvent() {
        this.data = new HashMap<>();
    }

    /**
     * 默认以当前时间作为事件时间
     */
    protected AbstractTypeEvent(Map<String, Object> data) {
        this.data = data;
    }

    protected AbstractTypeEvent(Date eventTime, Map<String, Object> data) {
        this.eventTime = eventTime;
        this.data = data;
    }

    public long getEventTimestamp() {
        return eventTime.getTime();
    }

    public abstract T copy();

    /**
     * 使用自定义的任意事件对象作为事件数据，用POJO代替Map方便写代码
     *
     * @param customEvent 自定义的事件对象
     * @param <E>         自定义事件对象的基类/接口类
     *
     */
    protected <E> void setWrappedEvent(E customEvent) {
        data.put(WRAPPED_EVENT_OBJ, customEvent);
    }

    @SuppressWarnings("unchecked")
    public <E> E getWrappedEvent() {
        return (E) data.get(WRAPPED_EVENT_OBJ);
    }

    public Object getParam(String key) {
        return data.get(key);
    }

    @SuppressWarnings("unchecked")
    public <C> C getObjectParam(String key) {
        return (C) data.get(key);
    }

    public int getIntParam(String key) {
        return (int) data.getOrDefault(key, 0);
    }

    public long getLongParam(String key) {
        return (long) data.getOrDefault(key, 0L);
    }

    public String getStringParam(String key) {
        return (String) data.getOrDefault(key, "");
    }

    public boolean getBooleanParam(String key) {
        return (boolean) data.getOrDefault(key, false);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
